/**
 * @class Timer
 * @class EventBus
 * @function getStyle
 * @function bind
 *
 */

class Timer {
  constructor(interval, timeOut, checkPause, onInterval, onTimeOut) {
    this.interval = interval;
    this.timeOut = timeOut;
    this.checkPause = checkPause;
    this.onInterval = onInterval;
    this.onTimeOut = onTimeOut;
    // eslint-disable-next-line
    this.id = Timer.count++;
    this.intervalId = null;
    this.isPause = false;
    this.count = 0;
  }

  static count = 0;

  start() {
    this.intervalId = setInterval(() => {
      if (this.checkPause() || this.isPause) return;
      this.count += this.interval;
      this.onInterval();
      this.timeOut -= this.interval;
      if (this.timeOut <= 0) {
        this.clear();
        this.onTimeOut();
        return;
      }
    }, this.interval);
  }

  stop() {
    this.isPause = true;
  }

  restart() {
    this.isPause = false;
  }

  speedUp(t) {
    this.timeOut -= t;
    this.count += t;
  }

  clear() {
    this.isPause = true;
    clearInterval(this.intervalId);
  }
}

class EventBus {
  constructor() {
    this.mutexBus = [];
    this.parallelBus = [];
  }

  mutexOn(key, action) {
    if (key && action) {
      const map = {};
      map.k = key;
      map.v = action;
      // eslint-disable-next-line
      for (let i = 0, busLength = this.mutexBus.length; i < busLength; i++) {
        const tempMap = this.mutexBus[i];
        if (tempMap.k === key) {
          this.mutexBus.splice(i, 1);
        }
      }
      this.mutexBus.push(map);
    }
  }

  mutexEmit(key) {
    if (key) {
      // eslint-disable-next-line
      for (let i = 0, busLength = this.mutexBus.length; i < busLength; i++) {
        const map = this.mutexBus[i];
        if (map.k === key) {
          return map.v();
        }
      }
    }
    return false;
  }

  parallelOn(key, action) {
    if (key && action) {
      const map = {};
      map.k = key;
      map.v = action;
      this.parallelBus.push(map);
    }
  }

  parallelEmit(key) {
    if (key) {
      // eslint-disable-next-line
      for (let i = 0, busLength = this.parallelBus.length; i < busLength; i++) {
        const map = this.parallelBus[i];
        if (map.k === key) {
          map.v();
        }
      }
    }
  }
}

function bindLongTouch(ele, longPress, doubleClick) {
  let timeOutEvent = 0;
  let lastClick = 0;

  function gtouchstart() {
    timeOutEvent = setTimeout(() => longPress(), 600);
    return false;
  }

  function gtouchend() {
    clearTimeout(timeOutEvent);
    if (Date.now() - lastClick < 300) {
      doubleClick();
      lastClick = 0;
    } else lastClick = Date.now();
    return false;
  }

  function gtouchmove() {
    clearTimeout(timeOutEvent);
    timeOutEvent = 0;
  }

  bind(ele, 'touchstart', gtouchstart);
  bind(ele, 'touchmove', gtouchmove);
  bind(ele, 'touchend', gtouchend);
}

function getStyle(elem, name) {
  if ('getComputedStyle' in window) return getComputedStyle(elem, null)[name];
  return elem.currentStyle[name];
}

function bind(obj, eventstr, callback) {
  if (obj.addEventListener) obj.addEventListener(eventstr, callback, false);
  else {
    obj.attachEvent(`on${eventstr}`, () => {
      callback.call(obj);
    });
  }
}
